package com.jinke.api.modules.app.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jinke.api.common.api.CommonResult;
import com.jinke.api.modules.app.enums.BalanceLogType;
import com.jinke.api.modules.app.enums.BalanceType;
import com.jinke.api.modules.app.enums.OrderStatus;
import com.jinke.api.modules.app.mapper.BalanceLogMapper;
import com.jinke.api.modules.app.model.BalanceLog;
import com.jinke.api.modules.app.model.Order;
import com.jinke.api.modules.app.request.BalanceLogQueryRequest;
import com.jinke.api.modules.app.service.BalanceLogService;
import com.jinke.api.modules.app.service.OrderService;
import com.jinke.api.modules.ums.model.UmsAdmin;
import com.jinke.api.modules.ums.service.UmsAdminService;
import com.jinke.api.modules.ums.vo.SimpleUser;
import com.jinke.api.security.util.AdminUserUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author macro
 * @since 2024-01-13
 */
@Service
public class BalanceLogServiceImpl extends ServiceImpl<BalanceLogMapper, BalanceLog> implements BalanceLogService {
                    //继承ServiceImpl泛型类<第一个泛型参数是数据库操作，第二个泛型是数据库实体类>   实现了BalanceLogService接口
    @Resource
    UmsAdminService umsAdminService;
    @Resource
    OrderService orderService;
    //依赖注入UmsAdminService类

    //对继承接口里的方式进行了具体的实现
    //对邮箱是否为空进行判断
    @Override
    public Page<BalanceLog> list(BalanceLogQueryRequest request) {
        //创建了一个ArrayList对象 ，命名为searchIds 并指定该列表元素的类型为INT
        List<Integer> searchIds = new ArrayList<>();
        //获取邮箱地址并赋值给email
        String email = request.getEmail();
        //对邮箱进行判断是否不为空
        if (StringUtils.isNotEmpty(email)) {//根据邮箱地址搜索用户，并将搜索结果的ID列表存储到searchId里面，如果搜索结果为空，则将该变量列表重新赋值为空就行
            //通过 LambdaQueryWrapper构建查询条件，指定泛型参数为UmsAdmin，针对这个类进行查询 ，然后创建一个新的，赋值给queryWrapper
            LambdaQueryWrapper<UmsAdmin> queryWrapper = new LambdaQueryWrapper<>();
            //在类里面查询emial，使用方式.lickRight有模糊查询（意思是以Email变量姐结尾的字符串）
            queryWrapper.likeRight(UmsAdmin::getEmail, email);
            //把后面的数据赋值给searchIds = 调用umsAdminService里的list方法（并传入已经构造好的查询条件），。stram（）将结果转换为流以便后续操作。
            //.map（）对该实体类里面的数据进行调用这里调用Id    .collectors()将流中的所有元素收集到一个列表中，生成了一个包含所有 UmsAdmin 对象的 ID 的列表
            searchIds = umsAdminService.list(queryWrapper).stream().map(UmsAdmin::getId).collect(Collectors.toList());
            //如果搜索结果为空，则将该变量列表重新赋值为-1
            if (CollectionUtils.isEmpty(searchIds)) {
                searchIds = Arrays.asList(-1);
            }
        }
        //请request中去除的id放到ids里面去
        List<String> ids = request.getIds();
        //初始化分页
        Page<BalanceLog> page = new Page<>(request.getPageNum(), request.getPageSize());
        //初始化查询条件
        QueryWrapper<BalanceLog> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                //判断searchIds列表是否为空，不为空继续 判断数据库中的userID是否存在searchids中，如果存在就进行IN查询，为空忽略
                .in(!searchIds.isEmpty(), BalanceLog::getUserId, searchIds)
                //判断 ids 列表是否不为空  不为空继续 判断数据库中的ID是否存在ids中，如果存在就进行IN查询，为空忽略
                .in(CollectionUtils.isNotEmpty(ids), BalanceLog::getId, ids)
                .eq(request.getType() != null, BalanceLog::getType, request.getType())
                .eq(request.getBalanceType() != null, BalanceLog::getBalanceType, request.getBalanceType())
                //判断请求中的OrderNo不为空且不为空字符串  不为空继续判断 字段是否相等
                .eq(StringUtils.isNotBlank(request.getOrderNo()), BalanceLog::getOrderNo, request.getOrderNo())
                //获取开始时间  大于等于
                .ge(request.getStartDate() != null, BalanceLog::getCreatedAt, request.getStartDate())
                //获取结束时间   小于等于
                .le(request.getEndDate() != null, BalanceLog::getCreatedAt, request.getEndDate())

                // 订单号匹配
                .in(CollectionUtils.isNotEmpty(request.getOrderNos()), BalanceLog::getOrderNo, request.getOrderNos())

                //设置查询结果按照id字段降序排序
                .orderByDesc(BalanceLog::getId);

        //获取当前登录用户的管理员信息。  显示userInfo权限 如果是销售
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        if (userInfo.isSeller()) { // 如果是销售只能看自己或者自己相关的数据
            Integer sellerId = userInfo.getId();
            wrapper.lambda().and(wp -> {
                wp.eq(BalanceLog::getUserId, sellerId)
                        .or().eq(BalanceLog::getSellerId, sellerId);
            });
        } else {
            wrapper.lambda().eq(request.getUserId() != null, BalanceLog::getUserId, request.getUserId());
        }

        //重新定义一个存储分页数据  放在pageResult = 调用page方法（page分页信息，wrapper查询条件的对象）
        Page<BalanceLog> pageResult = page(page, wrapper);
        // 获取列表中的用户ID
        List<Integer> userIds = pageResult.getRecords().stream().map(BalanceLog::getUserId).distinct().collect(Collectors.toList());
        // 关联用户数据
        Map<Integer, SimpleUser> usersMap = umsAdminService.getMaps(userIds);

        pageResult.getRecords().forEach(x -> {
            x.setUser(usersMap.getOrDefault(x.getUserId(), null));
        });

        return pageResult;
    }

    @Override
    public CommonResult<String> bug2() {
        List<String> aa = new ArrayList<>(61);
        List<String> orderNos = new ArrayList<>(61);
        //orderNos.add("202401A00003b91");
        orderNos.add("576630458507825788");
        orderNos.add("108912219758581");
        orderNos.add("202401A0000904a");
        orderNos.add("202401A0000eba8");
        orderNos.add("PO-211-20485841255030023");
        orderNos.add("202401A0000028a");
        orderNos.add("111-1455347-0400226");
        orderNos.add("112-0520235-2697847");
        orderNos.add("02-11431-12264");
        orderNos.add("202401A00000f0a");
        orderNos.add("202401A0000b054");
        orderNos.add("200011769401719");
        orderNos.add("200011674763589");
        orderNos.add("112-3738424-1201054-2");
        orderNos.add("112-3738424-1201054-1");
        orderNos.add("112-5622502-3392236");
        orderNos.add("114-2622747-3468217");
        orderNos.add("114-9932655-2840267");
        orderNos.add("112-4459775-8609860");
        orderNos.add("113-1996808-5257864");
        orderNos.add("114-3370105-3437846");
        orderNos.add("113-1175940-9388242");
        orderNos.add("113-5138613-1821054");
        orderNos.add("113-5868777-4474609");
        orderNos.add("113-2505315-8484231");
        orderNos.add("112-6622863-4305047");
        orderNos.add("114-6448243-8079447");
        orderNos.add("114-7134497-3348234");
        orderNos.add("111-0236180-4087438");
        orderNos.add("114-1407997-3489841");
        orderNos.add("113-3690923-6382638");
        orderNos.add("113-3313840-4113806");
        orderNos.add("112-7660458-8609060");
        orderNos.add("114-4061781-1051441");
        orderNos.add("112-6263126-2901043");
        orderNos.add("114-9043976-4265008");
        orderNos.add("112-3144075-8946633");
        orderNos.add("113-7890852-9872223");
        orderNos.add("112-3433290-0040231");
        orderNos.add("112-2471401-9630646");
        orderNos.add("111-5866109-7759443");
        orderNos.add("112-5576460-8634626");
        orderNos.add("112-1212623-9234637");
        orderNos.add("112-2284663-2020249");
        orderNos.add("112-1736472-8487433");
        orderNos.add("112-1871210-2628240");
        orderNos.add("111-7590559-4425001");
        orderNos.add("114-2764769-9315469");
        orderNos.add("113-5847532-1521816");
        orderNos.add("114-1060072-1923400");
        orderNos.add("113-3959013-0045017");
        orderNos.add("111-5885978-9537823");
        orderNos.add("111-4636968-0787413");
        orderNos.add("112-9980648-8296236");
        orderNos.add("112-1032635-9912256");
        orderNos.add("112-0423574-0977846");
        orderNos.add("112-6890779-1531418");
        for (String orderNo : orderNos) {
            Order order = orderService.lambdaQuery().eq(Order::getOrderNo, orderNo).eq(Order::getStatus,OrderStatus.CANCEL_REJECT.getValue()).one();
            if (ObjectUtils.isEmpty(order)){
                aa.add(orderNo);
            }else {
                BalanceLog balanceLog = lambdaQuery()
                        .eq(BalanceLog::getOrderNo, orderNo)
                        .eq(BalanceLog::getType, BalanceLogType.REFUND.getValue())
                        .one();
                if (ObjectUtils.isEmpty(balanceLog)){
                    aa.add(orderNo);
                }else {
                    //扣减对应用户余额
                    UmsAdmin umsAdmin = umsAdminService.getById(balanceLog.getUserId());
                    if (ObjectUtils.isEmpty(umsAdmin)){
                        aa.add(orderNo);
                    }else {
                      //扣钱加增加流水
                        kouqianAndBalance(orderNo, balanceLog, umsAdmin);
                    }
                }
            }
        }
        return CommonResult.success(JSON.toJSONString(aa));
    }

    /**
     * 扣钱加增加流水
     * @param orderNo
     * @param balanceLog
     * @param umsAdmin
     */
    @Transactional(rollbackFor = Exception.class)
    public void kouqianAndBalance(String orderNo, BalanceLog balanceLog, UmsAdmin umsAdmin) {
        umsAdminService.lambdaUpdate()
                .eq(UmsAdmin::getId, umsAdmin.getId())
                .setSql("balance = balance - " + balanceLog.getChangeValue())
                .update();
        //生成一条新的记录
        BalanceLog newBa = new BalanceLog();
        newBa.setUserId(balanceLog.getUserId());
        newBa.setChangeValue(balanceLog.getChangeValue().multiply(new BigDecimal("-1")));
        newBa.setAfterValue(umsAdmin.getBalance().subtract(balanceLog.getChangeValue()));
        newBa.setBalanceType(BalanceType.BALANCE);
        newBa.setOrderNo(orderNo);
        newBa.setRemark("取消订单，审核拒绝，造成退款bug，扣除多退余额");
        newBa.setType(BalanceLogType.RECHARGE);
        newBa.setSellerId(balanceLog.getSellerId());
        save(newBa);
    }
}
